package com.bruce.asurada.handler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.bruce.asurada.common.Result;
import com.bruce.asurada.common.constants.TokenConstants;
import com.bruce.asurada.common.dto.UserInfoDto;
import com.bruce.asurada.config.SsoProperties;
import com.bruce.asurada.constants.SSOConstants;
import com.bruce.asurada.dto.ImMessageDTO;
import com.bruce.asurada.util.HttpClientUtil;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class WebSocketHandler extends TextWebSocketHandler {
    private static final Map<String, WebSocketSession> USER_SESSIONS = new ConcurrentHashMap<>();
    
    @Resource
    private HttpClientUtil httpClientUtil;

    @Resource
    private  SsoProperties ssoProperties;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 验证令牌（从参数获取）
        String imSessionToken = (String) session.getAttributes().get(SSOConstants.IM_SESSION_TOKEN_COOKIE_NAME);
        if (imSessionToken == null) {
            session.close(CloseStatus.POLICY_VIOLATION.withReason("缺少imSession令牌"));
            return;
        }

        // 调用SSO验证令牌
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.add(TokenConstants.IM_SESSION_TOKEN_HEADER_NAME, imSessionToken);
        Result<UserInfoDto> result = httpClientUtil.get(ssoProperties.getServer().getVerifyImSessionUrl(), headers, new ParameterizedTypeReference<Result<UserInfoDto>>() {});
        if(null == result|| !result.isSuccess()){
            session.close(CloseStatus.POLICY_VIOLATION.withReason("imSession令牌无效"));
            return;
        }
        
        UserInfoDto userInfoDto = result.getData();
        if(null == userInfoDto){
            session.close(CloseStatus.POLICY_VIOLATION.withReason("用户imSession不存在"));
            return;
        }


        // 存储会话
        String username = userInfoDto.getUsername();
        USER_SESSIONS.put(username, session);
        session.getAttributes().put("username", username);
        log.info("用户[{}]WebSocket连接成功", username);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 处理消息（转发给接收者）
        ImMessageDTO imMessage = JSONObject.parseObject(message.getPayload(), ImMessageDTO.class);
        String sender = imMessage.getSender();
        String receiver = imMessage.getReceiver();
        String content = imMessage.getContent();
        try {
              if(StringUtils.isEmpty(receiver)){
                  sendSystemMessage(sender, "接收者不能为空");
                  return;
              }
              if(StringUtils.isEmpty(content)){
                  sendSystemMessage(sender, "消息内容不能为空");
                  return;
              }

              // 转发给接收者
              WebSocketSession receiverSession = USER_SESSIONS.get(receiver);
              if(receiverSession != null && receiverSession.isOpen()){
                  receiverSession.sendMessage(new TextMessage(content));
                  log.info("消息已发送给用户[{}]", receiver);
                  sendSystemMessage(sender, "消息已发送给用户"+receiver);
              }else{
                  sendSystemMessage(sender, "用户"+receiver+"不在线，消息未送达");
              }
            
        } catch (Exception e) {
            sendSystemMessage(sender, "消息发送失败：" + e.getMessage());
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String username = (String) session.getAttributes().get("username");
        if (username != null) {
            USER_SESSIONS.remove(username);
            log.info("用户[{}]WebSocket连接关闭", username);
        }
    }

    /**
     * 发送系统消息（如通知、错误提示）
     */
    private void sendSystemMessage(String username, String content) throws Exception {
        WebSocketSession session = USER_SESSIONS.get(username);
        if (session != null && session.isOpen()) {
            JSONObject systemMsg = new JSONObject();
            systemMsg.put("type", "system"); // 消息类型：系统通知
            systemMsg.put("content", content);
            systemMsg.put("timestamp", System.currentTimeMillis());
            session.sendMessage(new TextMessage(systemMsg.toString()));
        }
    }

    /**
     * 主动关闭用户会话（登出时调用）
     */
    public void closeUserSession(String username) {
        WebSocketSession session = USER_SESSIONS.get(username);
        if (session != null && session.isOpen()) {
            try {
                session.close(CloseStatus.NORMAL.withReason("用户登出"));
            } catch (Exception e) {
                log.error("关闭用户[{}]会话失败", username, e);
            }
        }
    }
}
